__author__ = 'xiaosu'

from octopus import db
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import UniqueConstraint
from datetime import datetime


# ROLE_USER = 0
# ROLE_ADMIN = 1

class Command(db.Model):
    __tablename__='command'
    commandid = db.Column(db.Integer,primary_key= True)
    command = db.Column(db.Text)
    description = db.Column(db.Text)
    typeid = db.Column(db.Integer, db.ForeignKey('commandtype.typeid'))

    def __init__(self,command,typeid):
        self.command=command
        self.typeid=typeid


class CommandType(db.Model):
    __tablename__='commandtype'
    typeid = db.Column(db.Integer,primary_key= True)
    typename = db.Column(db.String(64),unique= True)
    description = db.Column(db.Text)
    command=db.relationship('Command', backref='commandtype',
                                lazy='dynamic')

    def __init__(self,typename,description):
        self.typename=typename
        self.description=description

class Audit(db.Model):
    __tablename__='audit'
    auditid = db.Column(db.Integer,primary_key = True)
    userid = db.Column(db.Integer)
    actiontype = db.Column(db.Integer)
    #actiontype: 1 related to  login and logout,2 related to command,3 related to user,4 related to cluster
    action = db.Column(db.Text)
    timestamp = db.Column(db.DateTime,default=datetime.now())

    def __init__(self,userid,actiontype,action,timestamp=datetime.now()):
        self.userid=userid
        self.actiontype=actiontype
        self.action=action
        self.timestamp=timestamp

class Clusters(db.Model):
    __tablename__= 'clusters'
    clusterid = db.Column(db.Integer, primary_key = True)
    clustername = db.Column(db.String(64), unique = True)
    runuser = db.Column(db.String(64))
    audit = db.Column(db.Boolean, default = True)
    enabled = db.Column(db.Boolean, default = True)
    comment = db.Column(db.Text)
    hosts =  db.relationship('Hosts', backref = 'clusters', lazy = 'dynamic')


    def __repr__(self):
        return '<Class %r>' % (self.clustername)

    def __init__(self,clustername,runuser,audit=True,enabled=True,comment="no comment now"):
        self.clustername = clustername
        self.runuser = runuser
        self.audit = audit
        self.enabled = enabled
        self.comment = comment

class Hosts(db.Model):
    __tablename__ = 'hosts'
    hostid = db.Column(db.Integer , primary_key = True)
    host_ip = db.Column(db.String(15))
    login_name = db.Column(db.String(64))
    login_passwd = db.Column(db.String(64))
    root_passwd = db.Column(db.String(64))
    server_port = db.Column(db.Integer, default = 22)
    clusterid = db.Column(db.Integer, db.ForeignKey('clusters.clusterid'))
    audit = db.Column(db.Boolean, default = True)
    enabled = db.Column(db.Boolean, default = True)
    comment = db.Column(db.Text)
    full_ip=db.Column(db.String(15)) #ip address for sorting
    __table_args__=(UniqueConstraint('host_ip','login_name'),)


    def __repr__(self):
        return '<Host %r>' % (self.host_ip)


    def __init__(self,ipaddress,username,password,rootpasswd,serverport,clusterid,audit=True,enabled=True,comment="no comment now"):
        self.host_ip = ipaddress
        self.login_name = username
        self.login_passwd = password
        self.root_passwd = rootpasswd
        self.server_port = serverport
        self.audit = audit
        self.enabled = enabled
        self.comment = comment
        self.clusterid = clusterid
        full_tmp_ip=""
        for i in ipaddress.split("."):
            full_tmp_ip=full_tmp_ip+(3-len(i))*"0"+i+"."
        self.full_ip=full_tmp_ip[0:15]

users_clusters = db.Table ('users_clusters',
                           db.Column('userid',db.Integer,db.ForeignKey('users.userid')),
                           db.Column('clusterid',db.Integer,db.ForeignKey('clusters.clusterid')))

class Users(db.Model):
    __tablename__= 'users'
    userid = db.Column(db.Integer, primary_key = True)
    loginname = db.Column(db.String(64), unique = True)
    password = db.Column(db.String(64))
    realname = db.Column(db.String(64),unique=True)
    phonenumber = db.Column(db.String(11))
    email = db.Column(db.String(64))
    is_admin = db.Column(db.Boolean, default = False)
    is_locked = db.Column(db.Boolean, default = True)
    is_phone_authed = db.Column(db.Boolean, default = False)
    is_email_authed = db.Column(db.Boolean, default = False)
    # register_ip=
    managed = db.relationship('Clusters',
                              secondary = users_clusters,
                              backref = db.backref('users',lazy='dynamic'),
                              lazy='dynamic'
                              )
    comment = db.Column(db.Text)


    def __repr__(self):
        return '<User %r>' % (self.realname)

    def __init__(self,loginname,password,realname,phonenumber,email,comment="no comment now",is_admin=False,is_locked=True,is_phone_authed=False,is_email_authed=False):
        self.loginname=loginname
        self.password=password
        self.realname=realname
        self.phonenumber=phonenumber
        self.email=email
        self.is_admin=is_admin
        self.is_locked=is_locked
        self.is_phone_authed = is_phone_authed
        self.is_email_authed = is_email_authed
        self.comment=comment

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return unicode(self.userid)

    def add_permission(self,cluster):
        if not self.has_permission(cluster):
            self.managed.append(cluster)
        return self

    def del_permission(self,cluster):
        if  self.has_permission(cluster):
            self.managed.remove(cluster)
        return self

    def has_permission(self,cluster):
        return self.managed.filter(users_clusters.c.clusterid == cluster.clusterid).count() > 0

    def all_permissions(self):
        return self.managed.all()










# class Hosts_Groups(db.Model):
#     hostgroupid = db.Column(db.Integer, primary_key = True)
#     hostid = db.Column(db.Integer, db.ForeignKey('hosts.hostid'))

# class User(db.Model):
#     id = db.Column(db.Integer, primary_key = True)
#     nickname = db.Column(db.String(64), index = True, unique = True)
#     email = db.Column(db.String(120), index = True, unique = True)
#     role = db.Column(db.SmallInteger, default = ROLE_USER)
#
#     def __repr__(self):
#         return '<User %r>' % (self.nickname)